package nsqp

import (
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"

	"bgs/conf"
	"bgs/db"
	"bgs/grpc/imp/enums"
	handlers "bgs/nsqp/handlers/bgapi"
	"bgs/nsqp/topic"
	"bgs/nsqp/util"
	activityService "bgs/service/activity"
	brandService "bgs/service/brand"
	storeService "bgs/service/store"
	userService "bgs/service/user"
)

// BgapiProxy proxy bgapi nsq message
type BgapiProxy struct {
	slog *zap.SugaredLogger
	subs []*nsq.Consumer
}

// NewBgapiProxy initialization
func NewBgapiProxy(
	nsqConf conf.NsqSection,
	pgdao *db.PgDao,
	slog *zap.SugaredLogger,
	failover *util.NsqFailover,
	activityService *activityService.ActivityServiceImp,
	brandService *brandService.BrandServiceImp,
	storeService *storeService.StoreServiceImp,
	userService *userService.UserServiceImp,
) (proxy *BgapiProxy, err error) {
	proxy = &BgapiProxy{
		slog: slog,
	}
	config := nsq.NewConfig()

	// activityUserPvLogConsumer
	activityUserPvLogConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.AddActivityUserPvLog)
	activityUserPvLogConsumer, err := nsq.NewConsumer(activityUserPvLogConsumerTopic, appID, config)
	if err != nil {
		return
	}
	activityUserPvLogConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	activityUserPvLogConsumer.AddHandler(handlers.NewActivityUserPvLogHandler(pgdao, slog, activityService))
	err = activityUserPvLogConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, activityUserPvLogConsumer)

	// userPvLogConsumer
	userPvLogConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.AddUserPvLog)
	userPvLogConsumer, err := nsq.NewConsumer(userPvLogConsumerTopic, appID, config)
	if err != nil {
		return
	}
	userPvLogConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	userPvLogConsumer.AddHandler(handlers.NewUserPvLogHandler(pgdao, slog))
	err = userPvLogConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, userPvLogConsumer)

	// userFanConsumer
	userFanConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertUserFan)
	userFanConsumer, err := nsq.NewConsumer(userFanConsumerTopic, appID, config)
	if err != nil {
		return
	}
	userFanConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	userFanConsumer.AddHandler(handlers.NewUserFanHandler(pgdao, slog, userService))
	err = userFanConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, userFanConsumer)

	// userFollowConsumer
	userFollowConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertUserFollow)
	userFollowConsumer, err := nsq.NewConsumer(userFollowConsumerTopic, appID, config)
	if err != nil {
		return
	}
	userFollowConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	userFollowConsumer.AddHandler(handlers.NewUserFollowHandler(pgdao, slog, userService))
	err = userFollowConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, userFollowConsumer)

	// brandFanConsumer
	brandFanConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertBrandFan)
	brandFanConsumer, err := nsq.NewConsumer(brandFanConsumerTopic, appID, config)
	if err != nil {
		return
	}
	brandFanConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	brandFanConsumer.AddHandler(handlers.NewBrandFanHandler(pgdao, slog, brandService))
	err = brandFanConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, brandFanConsumer)

	// brandFollowConsumer
	brandFollowConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertBrandFollow)
	brandFollowConsumer, err := nsq.NewConsumer(brandFollowConsumerTopic, appID, config)
	if err != nil {
		return
	}
	brandFollowConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	brandFollowConsumer.AddHandler(handlers.NewBrandFollowHandler(pgdao, slog, userService))
	err = brandFollowConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, brandFollowConsumer)

	// storeFanConsumer
	storeFanConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertStoreFan)
	storeFanConsumer, err := nsq.NewConsumer(storeFanConsumerTopic, appID, config)
	if err != nil {
		return
	}
	storeFanConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	storeFanConsumer.AddHandler(handlers.NewStoreFanHandler(pgdao, slog, storeService))
	err = storeFanConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, storeFanConsumer)

	// storeFollowConsumer
	storeFollowConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.UpsertStoreFollow)
	storeFollowConsumer, err := nsq.NewConsumer(storeFollowConsumerTopic, appID, config)
	if err != nil {
		return
	}
	storeFollowConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	storeFollowConsumer.AddHandler(handlers.NewStoreFollowHandler(pgdao, slog, userService))
	err = storeFollowConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, storeFollowConsumer)

	// subMsgConsumer
	subMsgConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.MinaSendSubMsg)
	subMsgConsumer, err := nsq.NewConsumer(subMsgConsumerTopic, appID, config)
	if err != nil {
		return
	}
	subMsgConsumer.SetLogger(nsqLogger, nsq.LogLevelError)
	subMsgConsumer.AddHandler(handlers.NewMinaSubMsgHandler(slog))
	err = subMsgConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, subMsgConsumer)

	// Gracefully stop the consumer.
	// consumer.Stop()

	return
}
